#include "Ynbw.hpp"

Ynbw::Ynbw(Dictionary *dictionary)
          : MAXIMUM_PLAYERS_(6), MINIMUM_PLAYERS_(2), WORD_COUNT_(1024)
{
FUNCTION

  commonInitialization(dictionary);
}

Ynbw::Ynbw(const unsigned int maximumPlayers, const unsigned int minimumPlayers, Dictionary *dictionary)
          : MAXIMUM_PLAYERS_(maximumPlayers), MINIMUM_PLAYERS_(minimumPlayers), WORD_COUNT_(1024)
{
FUNCTION

  commonInitialization(dictionary);
}

Ynbw::~Ynbw()
{
FUNCTION

  delete gamePlayers_;
  delete dictionary_;
}

void Ynbw::commonInitialization(Dictionary *dictionary)
{
FUNCTION

  welcomeScreen();
  setPrompt("Say something, %PLAYER% - ");
  initializePlayers();
  dictionary_ = dictionary;
}

void Ynbw::initializePlayers()
{
FUNCTION

  Player **temporary = new Player*[MAXIMUM_PLAYERS_];
  gamePlayers_ = temporary;
}

void Ynbw::welcomeScreen()
{
FUNCTION

  std::cout << title << " (v" << version << ")\n";
  std::cout << banner << "\n";
}

void Ynbw::addPlayer(Player *gamePlayer)
{
FUNCTION

  gamePlayers_[numberPlayers_] = gamePlayer;
  numberPlayers_++;
}

Player *Ynbw::whoIsWinner()
{
FUNCTION

  for(unsigned int i = 0; i < numberPlayers_; i++)
  {
    if(!((gamePlayers_[i])->getIsOut()))
    {
      return gamePlayers_[i];
    }
  }
  return 0;
}

void Ynbw::setPrompt(const std::string prompt)
{
FUNCTION

  prompt_ = prompt;
}

void Ynbw::displayPrompt(std::string player)
{
  std::string displayable = prompt_;
  if(dictionary_->searchForWord(displayable, "%PLAYER%"))
  {
    displayable = displayable.erase(dictionary_->lastFoundOffset, 8);
    displayable = displayable.insert(dictionary_->lastFoundOffset, player);
  }
  std::cout << displayable;
}

int Ynbw::execute()
{
  try
  {
FUNCTION

    newGame();
    int returnValue = runGame();
    return returnValue;
  }
  catch(YnbwException theException)
  {
    if(theException.getExceptionNumber() != 0)
    {
      std::cerr << "===YNBW Error Reporter===\n";
      std::cerr << "   Error " << theException.getExceptionNumber() << ": ";
      std::cerr << theException.what() << "\n";
      std::cerr << "   This is a fatal error.\n";
      std::cerr << "   The application will be terminated.\n";
    }
    return theException.getExceptionNumber();
  }
  catch(std::exception theException)
  {
    std::cerr << "===YNBW Error Reporter===\n";
    std::cerr << "   Error " << EXCEPTION_STDEXCEPTION << ": Standard C++ Exception: ";
    std::cerr << theException.what() << "\n";
    std::cerr << "   This is a fatal error.\n";
    std::cerr << "   The application will be terminated.\n";
    return EXCEPTION_STDEXCEPTION;
  }
  catch(...)
  {
    std::cerr << "===YNBW Error Reporter===\n";
    std::cerr << "   Error " << EXCEPTION_BADEXCEPTION << ": Bad Exception: ";
    std::cerr << "   execute() has been thrown an exception that was not understood.\n";
    std::cerr << "   This is a fatal error.\n";
    std::cerr << "   The application will be terminated.\n";
    return EXCEPTION_BADEXCEPTION;
  }
}
